home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Taifun / Taifun 099 (1989-05-15)(Ossowski, Stefan)(DE)(PD).zip / Taifun 099 (1989-05-15)(Ossowski, Stefan)(DE)(PD).adf / PCQ / A68k.doc < prev    next >
Text File  |  1989-03-31  |  19KB  |  428 lines

  1.     A68k - a freely    distributable assembler    for the    Amiga
  2.  
  3.             by Charlie Gibbs
  4.  
  5.              with special thanks to
  6.         Brian R. Anderson and Jeff Lydiatt
  7.  
  8.           (Version 1.2 - July 11, 1988)
  9.  
  10.      Note: This    program    is NOT Public Domain.  Permission is given
  11. to freely distribute this program provided no fee is charged, and this
  12. documentation file is included with the    program.
  13.  
  14.      This assembler is based on    Brian R. Anderson's 68000 cross-
  15. assembler published in Dr. Dobb's Journal, April through June 1986.
  16. I have converted it to produce AmigaDOS-format object modules, and
  17. have made many enhancements, such as macros and    include    files.
  18.  
  19.      My    first step was to convert the original Modula-2    code into C.
  20. I did this for two reasons.  First, I had access to a C    compiler, but
  21. not a Modula-2 compiler.  Second, I like C better anyway.
  22.  
  23.      The executable code generator code    (GetObjectCode and MergeModes)
  24. is essentially the same    as in the original article, aside from its
  25. translation into C.  I have almost completely rewritten    the remainder
  26. of the code, however, in order to remove restrictions, add enhancements,
  27. and adapt it to    the AmigaDOS environment.  Since the only reference book
  28. available to me    was the    AmigaDOS Developer's Manual (Bantam, February
  29. 1986), the assembler and the remainder of this document    work in    terms
  30. of that    book.
  31.  
  32.  
  33. RESTRICTIONS
  34.  
  35.      Let's get these out of the way first.  There are a few things that I
  36. have not yet implemented, and some outright bugs that would take too long
  37. to correct for this version.
  38.  
  39.       o    The verification file (-v) option is not supported.  Diagnostic
  40.     messages always    appear on the console.    They also appear in the
  41.     listing    file, however (see extensions below).  You can produce
  42.     an error file by redirecting console output to a file -    the
  43.     line number counter and    final summary are displayed on stderr
  44.     so you can still see what's happening.
  45.  
  46.       o    The file names in the include directory    list (-i) must be separated
  47.     by commas.  The    list may not be    enclosed in quotes.
  48.  
  49.       o    Labels assigned    by EQUR    and REG    directives are case-sensitive.
  50.  
  51.       o    The following directives are not supported, and    will be    flagged    as
  52.     invalid    op-codes:
  53.  
  54.         RORG
  55.         OFFSET
  56.         NOPAGE
  57.         LLEN
  58.         PLEN
  59.         NOOBJ
  60.         FAIL
  61.         FORMAT
  62.         NOFORMAT
  63.         MASK2
  64.  
  65.     I feel that NOPAGE, LLEN, and PLEN should not be defined within    a
  66.     source module.    It doesn't make sense to me to have to change your
  67.     program    just because you want to print your listings on    different
  68.     paper.    The command-line option    "-p" (see below) can be used as a
  69.     replacement for    PLEN.
  70.  
  71.  
  72. EXTENSIONS
  73.  
  74.      Now for the good stuff:
  75.  
  76.       o    Labels can be any length that will fit onto one    source line
  77.     (currently 127 bytes maximum).    Since labels are stored    on the
  78.     heap, the number of labels that    can be processed is limited only
  79.     by available memory, which can be increased by using the "-w"
  80.     option (see below).
  81.  
  82.       o    Since section data and user macro definitions are stored on the
  83.     same heap as the symbol    table (see above), they    too are    limited
  84.     only by    available memory.  (Actually, there is a hard-coded limit
  85.     of 32767 sections, but I doubt anyone will run into that one.)
  86.  
  87.       o    The only values    a label    cannot take are    the register names - the
  88.     assembler can distinguish between the same name    used as    a label,
  89.     instruction name or directive, macro name, or section name.
  90.  
  91.       o    Section    and user macro names appear in the symbol table    dump, and
  92.     will also be cross-referenced.    Their names can    be the same as any
  93.     label (see above); the assembler can sort them out.
  94.  
  95.       o    Includes and macro calls can be    nested indefinitely, limited only
  96.     by available memory.  The message "Secondary heap overflow -
  97.     assembly terminated" will be displayed if memory is exhausted.
  98.     You can    increase the size of this heap using the -w parameter
  99.     (see below).  Recursive    macros are supported; recursive    includes
  100.     will, of course, result    in a loop that will be broken only when
  101.     the heap overflows.
  102.  
  103.       o    The EVEN directive forces alignment on a word (2-byte) boundary.
  104.     It does    the same thing as CNOP 0,2.
  105.     (This one is left over from the    original code.)
  106.  
  107.       o    Branch (Bcc) instructions to a previously-defined label    will be
  108.     automatically converted    to short form if possible.  This feature is
  109.     not available for forward branches, since in pass 1 the    assembler
  110.     doesn't yet know how far the branch must go.
  111.  
  112.       o    Backward references to labels within the current CODE section
  113.     will be    converted to PC    relative addressing with displacement
  114.     if this    mode is    legal for the instruction.
  115.  
  116.       o    If a MOVEM instruction only specifies one register, it is converted
  117.     to the corresponding MOVE instruction.    Instructions such as
  118.     MOVEM D0-D0,label will not be converted, however.
  119.  
  120.       o    ADD, SUB, and MOVE instructions    will be    converted to ADDQ, SUBQ,
  121.     and MOVEQ respectively if possible.  Instructions coded    explicitly
  122.     as (for    example) ADDA or ADDI will not be converted.
  123.  
  124.       o    ADD, CMP, SUB, and MOVE    to an address register are converted to
  125.     ADDA, CMPA, SUBA, and MOVEA respectively, except if an ADD, SUB,
  126.     or MOVE    instruction has    already    been converted to quick    form.
  127.  
  128.       o    ADD, AND, CMP, EOR, OR,    and SUB    of an immediate    value are converted
  129.     to ADDI, ANDI, CMPI, EORI, ORI,    and SUBI respectively (unless the
  130.     address    register or quick conversion above has already been done).
  131.  
  132.       o    If both    operands of a CMP instruction are postincrement    mode, the
  133.     instruction is converted to CMPM.
  134.  
  135.       o    Operands of the    form 0(An) will    be treated as (An).
  136.  
  137.       o    The SECTION directive allows a third parameter.     This can be
  138.     specified as either CHIP or FAST (upper- or lower-case).  If this
  139.     parameter is present, the hunk will be written with the    MEMF_CHIP
  140.     or MEMF_FAST bit set.  This allows you to produce "pre-ATOMized"
  141.     object modules.
  142.  
  143.       o    The synonyms DATA and BSS are accepted for SECTION directives
  144.     starting data or BSS hunks.  The CHIP and FAST options mentioned
  145.     above can also be used,    e.g. BSS name,CHIP.
  146.  
  147.       o    The following synonyms have been implemented for compatibility
  148.     with the Aztec assembler:
  149.         CSEG is    treated    the same as CODE or SECTION name,CODE
  150.         DSEG is    treated    the same as DATA or SECTION name,DATA
  151.  
  152.       o    The ability to produce Motorola    S-records is retained from the
  153.     original code.    The -s option causes the assembler to produce
  154.     S-format instead of AmigaDOS format.  Relocatable code cannot be
  155.     produced in this format.
  156.  
  157.       o    Error messages consist of three    parts.
  158.         The    position of the    offending line is given    as a line number
  159.     within the current module.  If the line    is within a macro expan-
  160.     sion or    INCLUDE    file, the position of the macro    call or    INCLUDE
  161.     statement in the outer module is given as well.     This process
  162.     is repeated until the outermost    source module is reached.
  163.         Next, the offending    source line itself is listed.
  164.         Finally, the errors    for that line are displayed.  A    flag
  165.     (^) is placed under the    column where the error was detected.
  166.  
  167.       o    Named local labels are supported.  These work the same as the
  168.     local labels supported by the Metacomco    assembler (nnn$) but
  169.     can be formed in the same manner as normal labels, except that
  170.     they must be preceded by a backslash.
  171.  
  172.       o    The following synonyms have been implemented for compatibility
  173.     with the Assempro assembler:
  174.         ENDIF is treated the same as ENDC
  175.         = is treated the same as EQU
  176.         | is treated the same as ! (logical OR)
  177.  
  178.       o    Quotation marks    (") can be used as string delimiters
  179.     as well    as apostrophes (').  Any given string must begin
  180.     and end    with the same delimiter.  This allows such statements
  181.     as the following:
  182.         MOVEQ    '"',D0
  183.         DC.B    "This is Charlie's assembler."
  184.     Note that you can still    define an apostrophe within a string
  185.     delimited by apostrophes if you    double it, e.g.
  186.         MOVEQ    """",D0
  187.         DC.B    'This is Charlie''s assembler.'
  188.  
  189.       o    If any errors are found    in the assembly, the object code file
  190.     will be    scratched, unless you specified    the -k (keep) flag
  191.     on the command line.
  192.  
  193.       o    The symbol .A68K (note upper case) is automatically defined
  194.     as a SET symbol    having an absolute value of 1.    This enables
  195.     a source program to determine whether it is being assembled
  196.     on this    assembler.
  197.  
  198.       o    A zeroth positional macro parameter (\0) is supported.    It
  199.     is replaced by the length of the macro call (B,    W, or L,
  200.     defaulting to W).  For instance, given the macro:
  201.         moov    MACRO
  202.             move.\0    \1,\2
  203.             ENDM
  204.     the macro call
  205.             moov.l    d0,d1
  206.     would be expanded as
  207.             move.l    d0,d1
  208.  
  209.  
  210. HOW TO USE IT
  211.  
  212.      The command-line syntax to    run the    assembler is as    follows:
  213.  
  214.     a68k <source file>
  215.         [-d]
  216.         [-e<equate file>]
  217.         [-h<header file>]
  218.         [-i<include dirlist>]
  219.         [-k]
  220.         [-l<listing file>]
  221.         [-o<object file>]
  222.         [-p<page depth>]
  223.         [-q[<quiet interval>]]
  224.         [-s]
  225.         [-t]
  226.         [-w[<primary-heap-size>][,secondary-heap-size]]
  227.         [-x<listing file>]
  228.         [-z[<debug-start-line>][,debug-end-line]]
  229.  
  230. These options can be given in any order, and the source    file name can
  231. appear before all switches, after them,    or anywhere in the middle.
  232. Option values, if any, must immediately    follow the keyword with
  233. no intervening spaces.
  234.  
  235.      If    the -o keyword is omitted, the object file will    be given a default
  236. name.  It is created by    replacing all characters after the last    period in
  237. the source file    name by    "o".  For example, if the source file name is
  238. "myprog.asm", the object file name defaults to "myprog.o".  A source name
  239. of "my.new.prog.asm" produces a default object file name of "my.new.prog.o".
  240. If the source file name    does not contain a period, ".o" is appended to it
  241. to produce the default object file name.
  242.  
  243.      The default value for the listing file name is arrived at in the same
  244. way as the object file name, except that ".lst" is appended instead of ".o".
  245. If you don't specify this parameter, no listing file will be produced.
  246. If you specify -x (see below), -l (with    the default name) is assumed,
  247. although you can still use this    parameter if you wish.
  248.  
  249.      The default value for the equate file name    is arrived at in the same
  250. way as the object file name, except that ".equ" is appended instead of ".o".
  251.  
  252.      The include directory list    is a list of directory names separated by
  253. commas.     No embedded blanks are    allowed.  For example, the specification
  254.     -imylib,df1:another.lib
  255. will cause include files to be searched    for first in the current directory,
  256. then in    "mylib", then in "df1:another.lib".
  257.  
  258.      The -d keyword causes symbol table    entries    (hunk_symbol) to be written
  259. to the object module for the use of symbolic debuggers.
  260.  
  261.      The -k keyword causes the object file to be kept if any errors were
  262. found.    Otherwise, it will be scratched    if any errors occurred.
  263.  
  264.      The -l keyword causes a listing file to be    produced.  If you want
  265. the listing file to include a symbol table dump    and cross-reference,
  266. use the    -x keyword instead (see    below).
  267.  
  268.      The -p keyword causes the page depth to be    set to the specified value.
  269. If omitted, a default of 60 lines (-p60) is assumed.
  270.  
  271.      The -q keyword changes the    interval at which A68k displays    the
  272. current    line number (the default is every 10 lines, i.e. -q10).     If
  273. you specify -q0    or -q without a    value, no line numbers will be displayed.
  274. This will speed    up assemblies slightly by reducing console I/O.
  275.  
  276.      The -s keyword, if    specified, causes the object file to be    written    in
  277. Motorola S-record format.  If omitted, AmigaDOS    format will be produced.
  278. The default name for an    S-record file has ".s" appended to the source name,
  279. rather than ".o"; this can still be overridden with the -o keyword, though.
  280.  
  281.      The -t keyword allows tabs    in the source file to be passed    through
  282. to the listing file, rather than being expanded.  In addition, tabs will
  283. be generated in    the listing file to skip from the object code to the
  284. source statement, etc.    This can greatly reduce    the size of the    listing
  285. file, as well as making    it quicker to produce.    Do not use this    option
  286. if you will be displaying or listing the list file on a    device which
  287. does not respond to a tab at every 8th position.
  288.  
  289.      The -w keyword specifies the size of the heaps used.  The primary heap
  290. stores the symbol table, user macro text, relocation information, and
  291. cross-reference    information.  The secondary heap stores    information for
  292. nested macro calls and include files.  The primary heap    size defaults to
  293. 32768 bytes, which should be enough for    all but    the largest assemblies.
  294. The secondary heap size    defaults to 1024 bytes,    which should be    enough
  295. unless you use very deeply nested macros and/or    include    files with long
  296. path names.  You can specify either or both parameters.     For example:
  297.     -w40000        secondary heap size remains at 1024 bytes
  298.     -w,2000        primary    heap size remains at 32768 bytes
  299.     -w40000,2000    increases the size of both heaps
  300. If you're really tight for memory, and are assembling small modules, you
  301. can use    this keyword to    shrink the heaps below their default sizes.
  302. At the end of an assembly, a message will be displayed giving the
  303. amount of heap space actually used, in the form    of the -w command
  304. you would have to enter    to allocate the    mininum    heap space.
  305. See below for a    layout of the heaps.
  306.  
  307.      The -x keyword works the same as -l, except that a    symbol table
  308. dump, including    cross-reference    information, will be added to the end
  309. of the listing file.
  310.  
  311.      The -z keyword is provided    for debugging purposes.     You can cause
  312. the assembler to list a    range of each lines, complete with line    number
  313. and current location counter value, during both    passes.     For example:
  314.     -z        lists all source lines
  315.     -z100,200    lists lines 100    through    200
  316.     -z100        lines all lines    starting at 100
  317.     -z,100        lines the first    100 lines
  318.  
  319.  
  320.      If    you wish to override the default object    and (optionally) listing
  321. file names, you    can omit the -o    and -l keywords.  The assembler    interprets
  322. the first three    parameters without leading hyphens as the source, object,
  323. and listing file names respectively.  Anything over three file names is    an
  324. error, as is attempting    to respecify a file name with the -o or    -l keywords.
  325.  
  326.  
  327.      The primary heap is built from both ends.    Symbol table entries
  328. (including labels) and macro text are stored during pass 1.  Cross-reference
  329. data is    stored during pass 2.  Relocation information is also stored during
  330. pass 2,    but is cleared at the end of each SECTION.  Since it is    no longer
  331. needed once dumped, the    space is freed for re-use by the next section's
  332. relocation information.     The expression    parser also uses the primary heap
  333. to store its working stacks - this space is freed as soon as an    expression
  334. has been evaluated.
  335.      The fixed portion of each symbol table entry occupies 16 bytes.  The
  336. labels and macro text occupy just enough space to hold their strings
  337. (including the end-of-string delimiter)    - they are all pointed to by fixed
  338. symbol table entries.  Relocation entries occupy 10 bytes each.
  339. Cross-reference    entries    are 12 bytes long - each holds four references to
  340. one symbol.  The expression parser creates temporary entries for terms
  341. (10 bytes each)    and operators (4 bytes each).  Since terms are combined
  342. as soon    as possible, the parser    almost never needs to store the    entire
  343. expression on the heap.
  344.      The diagram below illustrates the layout of the primary heap.  High
  345. memory addresses are at    the top    of the diagram,    while low addresses are
  346. at the bottom.    The names on the left of the diagram are the names of the
  347. pointers to the    various    tables within the heap.
  348.  
  349.     Heap + maxheap ------------->  ___________________________
  350.                       |                  |
  351.                       |      Symbol table          |
  352.     struct SymTab *SymStart     ---> |___________________________|
  353.                       |                  |
  354.                       |      Symbol references      |
  355.     struct Ref *RefStart -------> |___________________________|
  356.                       |                  |
  357.                       |      (unused space)      |
  358.     char *HeapLim --------------> |___________________________|
  359.                       |                  |
  360.                       |      Relocation data      |
  361.     struct RelTab *RelStart    ----> |___________________________|
  362.                       |                  |
  363.                       |      Labels and macro text      |
  364.     char *Heap -----------------> |___________________________|
  365.  
  366.      Note that the pointers are    to various types.  This    makes for
  367. lots of    interesting casts.  (Ain't C fun?)  Since the relocation
  368. data is    cleared    at the end of each section, HeapLim will move up and
  369. down.  The "high-water mark" is stored in char *HighHeap, which is
  370. used solely to produce the memory usage    message    at the end of the
  371. assembly.  Note    that a program may consist of a    section    containing
  372. many relocatable references, followed by a section with    fewer
  373. relocatable references but lots    of symbol references.  In this case,
  374. RefStart might end up below HighHeap, and the final message would
  375. indicate that more heap    space was used than was    available.  This is
  376. not an error - only if RefStart    hits HeapLim will an error be reported.
  377.  
  378.  
  379.      The secondary heap    is also    built from both    ends, but it grows and
  380. shrinks    according to how many macros and include files are currently open.
  381. At all times there will    be at least one    entry on the heap, for the original
  382. source code file.
  383.      The bottom    of the heap holds the names of the source code file and
  384. any macro or include files that    are currently open.  The full path is
  385. given.    A null string is stored    for user macros.  Macro    arguments are
  386. stored by additional strings, one for each argument in the macro call line.
  387. All strings are    stored in minimum space, similar to the    labels and user
  388. macro text on the primary heap.     File names are    pointed    to by the fixed
  389. table entries (see below) - macro arguments are    accessed by stepping past
  390. the macro name to the desired argument,    unless NARG would be exceeded.
  391.      The fixed portion of the heap is built down from the top.    Each entry
  392. occupies 16 bytes.  Enough information is stored to return to the proper
  393. position in the    outer file once    the current macro or include file has been
  394. completely processed.
  395.      The diagram below illustrates the layout of the secondary heap.
  396.  
  397.     Heap2 +    maxheap2 ----------->  ___________________________
  398.                       |                  |
  399.                       |      Input    file table      |
  400.     struct InFCtl *InF ---------> |___________________________|
  401.                       |                  |
  402.                       |      Parser operator stack      |
  403.     struct OpStack *Ops --------> |___________________________|
  404.                       |                  |
  405.                       |      (unused space)      |
  406.     struct TermStack *Term -----> |___________________________|
  407.                       |                  |
  408.                       |      Parser term stack      |
  409.     char *NextFNS --------------> |___________________________|
  410.                       |                  |
  411.                       |      Input    file name stack      |
  412.     char *Heap2 ----------------> |___________________________|
  413.  
  414.      The "high-water mark" for NextFNS is stored in char *High2,
  415. and the    "low-water mark" (to stretch a metaphor) for InF is stored
  416. in struct InFCtl *LowInF.  Again, these    figures    are used only to
  417. determine the maximum heap usage.
  418.  
  419.  
  420.      Please send me any    bug reports, flames, etc.  I can be reached
  421. on Mind    Link (604/533-2312), at    any Panorama (PAcific NORthwest    AMiga
  422. Association) meeting, or via Jeff Lydiatt or Larry Phillips.
  423. (I don't have the time or money to live on Usenet or CompuServe, etc.)
  424.  
  425.                 Charlie    Gibbs
  426.  
  427.      (I    can't give a mailing address right now because I'm moving.)
  428.